<!DOCTYPE html>
<html>
<head>
<title>Frequency Spectrum</title>
</head>
<body>
<canvas id="canvas" width="500" height="350"></canvas>
<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // Style settings
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 1.5;
    ctx.font = '18px Arial';

    // Coordinate system parameters
    const yBase = 260;
    const xAxisStartX = 80;
    const pixelsPerKHz = 15;
    const sidebandHeight = 50;
    const carrierHeight = 180;

    // Helper function to convert frequency to x-coordinate
    function getX(f) {
        // Center the 300 kHz mark
        const xCenter = canvas.width / 2;
        return xCenter + (f - 300) * pixelsPerKHz;
    }

    // --- Drawing starts here ---

    // 1. Draw Axes
    ctx.beginPath();
    // Y-axis (vertical)
    ctx.moveTo(xAxisStartX, yBase + 20); // Extend slightly below x-axis
    ctx.lineTo(xAxisStartX, 30);
    // Arrowhead for Y-axis
    ctx.moveTo(xAxisStartX, 30);
    ctx.lineTo(xAxisStartX - 5, 40);
    ctx.moveTo(xAxisStartX, 30);
    ctx.lineTo(xAxisStartX + 5, 40);

    // X-axis (horizontal)
    ctx.moveTo(xAxisStartX - 20, yBase);
    ctx.lineTo(450, yBase);
    ctx.stroke();

    // 2. Draw Labels and Ticks
    // Y-axis labels
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText('amplitude', 45, 145);

    ctx.textAlign = 'right';
    ctx.fillText('0', xAxisStartX - 8, yBase);

    // X-axis ticks and labels
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    const freqs = [292, 300, 308];
    freqs.forEach(f => {
        const x = getX(f);
        ctx.beginPath();
        ctx.moveTo(x, yBase);
        ctx.lineTo(x, yBase + 5);
        ctx.stroke();
        ctx.fillText(f, x, yBase + 10);
    });
    
    // X-axis title 'f / kHz'
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    const fLabelX = getX(308) + 30;
    const fLabelY = yBase;
    // Draw 'f' in italics
    ctx.font = 'italic 18px Arial';
    ctx.fillText('f', fLabelX, fLabelY);
    const fWidth = ctx.measureText('f').width;
    // Draw '/ kHz' in regular font
    ctx.font = '18px Arial';
    ctx.fillText(' / kHz', fLabelX + fWidth, fLabelY);
    
    // Figure caption
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText('Fig. 5.1', canvas.width / 2, 330);

    // 3. Draw Carrier Spike
    ctx.beginPath();
    ctx.moveTo(getX(300), yBase);
    ctx.lineTo(getX(300), yBase - carrierHeight);
    ctx.stroke();

    // 4. Draw Sidebands
    // Lower Sideband (LSB)
    ctx.beginPath();
    ctx.moveTo(getX(292), yBase); // Start at (292, 0)
    ctx.quadraticCurveTo(getX(292.8), yBase - sidebandHeight * 0.6, getX(294), yBase - sidebandHeight * 0.7);
    ctx.quadraticCurveTo(getX(295.2), yBase - sidebandHeight * 0.8, getX(296.5), yBase - sidebandHeight * 0.6);
    ctx.quadraticCurveTo(getX(297.8), yBase - sidebandHeight * 0.9, getX(298.8), yBase - sidebandHeight * 0.5);
    ctx.quadraticCurveTo(getX(299.7), yBase - sidebandHeight * 0.4, getX(300), yBase); // End at (300, 0)
    ctx.stroke();

    // Upper Sideband (USB) - mirror image of LSB
    ctx.beginPath();
    ctx.moveTo(getX(300), yBase); // Start at (300, 0)
    ctx.quadraticCurveTo(getX(300.3), yBase - sidebandHeight * 0.4, getX(301.2), yBase - sidebandHeight * 0.5);
    ctx.quadraticCurveTo(getX(302.2), yBase - sidebandHeight * 0.9, getX(303.5), yBase - sidebandHeight * 0.6);
    ctx.quadraticCurveTo(getX(304.8), yBase - sidebandHeight * 0.8, getX(306), yBase - sidebandHeight * 0.7);
    ctx.quadraticCurveTo(getX(307.2), yBase - sidebandHeight * 0.6, getX(308), yBase); // End at (308, 0)
    ctx.stroke();

</script>
</body>
</html>